-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.


local skynet = require 'skynet'
local fw_upgrade = require 'unit_manager.class.logic_fw.upgrade.fw_upgrade'
local fpga_upgrade = require 'unit_manager.class.logic_fw.fpga.fpga_upgrade'
local lu = require 'luaunit'
local fw_mgmt_client = require 'general_hardware.client'
local signal = require 'unit_manager.class.logic_fw.signal'
local fpga_signal = require 'unit_manager.class.logic_fw.fpga.fpga_signal'
local factory = require 'factory'
local fructl = require 'mcu.upgrade.fructl_handler'
local valid_handle = require 'unit_manager.class.logic_fw.upgrade.valid'
local fpga_process = require 'unit_manager.class.logic_fw.fpga.fpga_process'
local fpga_self_test = require 'unit_manager.class.logic_fw.fpga.fpga_self_test'
local process_handle = require 'unit_manager.class.logic_fw.upgrade.process'
local vos = require 'utils.vos'

local active_success = false

local SYSTEM_ID = 1

local manager = {
    logic_fw = {
        [1] = {
            csr = {
                Name = "L1_FPGA"
            },
            position = "010103",
            check_update_ver = function()
            end
        }
    },
    exp_boards = {
        [1] = {
            position = "010103",
            task_update_logic_version = function()
            end
        }
    }
}

TestLogicalFwSignal = {}

function TestLogicalFwSignal:setupClass()
    skynet.fork = function(cb)
        cb()
    end

    self.old_prepare_upgrade = fw_upgrade.prepare_upgrade
    fw_upgrade.prepare_upgrade = function()
    end
    self.old_process_upgrade = fw_upgrade.process_upgrade
    fw_upgrade.process_upgrade = function()
    end
    self.old_finish_upgrade = fw_upgrade.finish_upgrade
    fw_upgrade.finish_upgrade = function()
        return true
    end

    fpga_upgrade.active_process = function()
        return true
    end

    self.old_upgrade_fpga_by_flash = process_handle.upgrade_fpga_by_flash
    process_handle.upgrade_fpga_by_flash = function(self, fpga_signal, file_path)
        if file_path == '1' then
            return 0
        end
        return -1
    end

    self.old_upgrade_component_cpld = process_handle.upgrade_component_cpld
    process_handle.upgrade_component_cpld = function(self, db, system_id, 
    fw_list, cfg_list, file_path, upgrade_list, hot_upgrade)
        if db == 1 then
            return 0
        end
        return -1
    end

    self.old_get_instance = fpga_self_test.get_instance
    fpga_self_test.get_instance = function()
        return {
            get_fpga_self_test_result = function()
                return 0
            end
        }
    end

    self.old_finish_upgrade = fpga_upgrade.finish_upgrade
    fpga_upgrade.finish_upgrade = function()
    end

    self.old_get_file_accessible = vos.get_file_accessible
    vos.get_file_accessible = function(file_path)
        if file_path ~= '/dev/mtd0' then
            return 0
        end
    end

    self.old_validate_upgarde_process = process_handle.validate_upgarde_process
    process_handle.validate_upgarde_process = function(self, fw_list, cfg_list, file_path)
        if #fw_list == 0 then
            return false
        end
        return true
    end

    self.old_cpld_valid = fw_upgrade.cpld_valid
    fw_upgrade.cpld_valid = true

    fw_mgmt_client.FirmwareActiveFirmwareActiveUpdateActiveStatus = function()
    end

    fw_mgmt_client.FirmwareActiveFirmwareActiveActiveProcessReply = function()
        -- 生效流程进入此函数表示成功，将结果置为true
        active_success = true
    end

    factory.get_obj = function()
        return manager
    end
    fw_mgmt_client.UpdateServiceUpdateServiceUpdateUpgradeStatus = function()
    end
end

function TestLogicalFwSignal:teardownClass() 
    fw_upgrade.cpld_valid = self.old_cpld_valid
    fw_upgrade.prepare_upgrade = self.old_prepare_upgrade
    fw_upgrade.process_upgrade = self.old_process_upgrade
    fw_upgrade.finish_upgrade = self.old_finish_upgrade
    process_handle.upgrade_fpga_by_flash = self.old_upgrade_fpga_by_flash
    process_handle.upgrade_component_cpld = self.old_upgrade_component_cpld
    fpga_self_test.get_instance = self.old_get_instance
    fpga_upgrade.finish_upgrade = self.old_finish_upgrade
    vos.get_file_accessible = self.old_get_file_accessible
    process_handle.validate_upgarde_process = self.old_validate_upgarde_process
end

-- 测试CPLD升级生效流程
function TestLogicalFwSignal:test_active_callback()
    signal.active_callback(_, SYSTEM_ID, 'CPLD')
    lu.assertEquals(active_success, true)
    lu.assertEquals(fw_upgrade.cpld_valid, true)
end

-- 测试CPLD升级prepare流程
function TestLogicalFwSignal:test_upgrade_prepare_callback()
    local ok, err = pcall(signal.upgrade_prepare_callback, _, SYSTEM_ID, 'Cpld', '')
    lu.assertEquals(ok, true, err)
end

-- 测试CPLD升级process流程
function TestLogicalFwSignal:test_upgrade_process_callback()
    local ok = pcall(signal.upgrade_process_callback, _, SYSTEM_ID, 'Cpld', '')
    lu.assertEquals(ok, true)
end

-- 测试CPLD升级finish流程
function TestLogicalFwSignal:test_upgrade_finish_callback()
    fructl.get_chassis_power_status = function()
        return "ON"
    end
    valid_handle.get_validating_flag = function()
        return false
    end
    local ok = pcall(signal.upgrade_finish_callback, _, SYSTEM_ID, 'Cpld')
    lu.assertEquals(ok, true)

    fructl.get_chassis_power_status = function()
        return "OFF"
    end
    valid_handle.get_validating_flag = function()
        return true
    end
    fw_upgrade.finish_upgrade = function()
        return true
    end
    fw_mgmt_client.UpdateServiceUpdateServiceUpdateUpgradeStatus = function()
    end
    fw_mgmt_client.UpdateServiceUpdateServiceFinishReply = function()
    end
    signal.db = {
        CustomizeSign = function()
        end
    }
    signal.fw_list = {
        [1] = {
            valid_mode = 2
        }
    }
    signal.upg_cfg_list = {
        [1] = {
            check_fw_uid_exist = function()
                return true
            end
        }
    }
    ok = pcall(signal.upgrade_finish_callback, _, SYSTEM_ID, 'Cpld')
    lu.assertEquals(ok, true)

    signal.fw_list = {
        [1] = {
            valid_mode = 3
        }
    }
    ok = pcall(signal.upgrade_finish_callback, _, SYSTEM_ID, 'Cpld')
    lu.assertEquals(ok, true)
end

-- 测试FPGA升级生效流程
function TestLogicalFwSignal:test_fpga_active_callback()
    --FpgaLoadResetb不为0时代表需要生效
    active_success = false
    fpga_signal.active_callback(_, SYSTEM_ID, 'FPGA')
    lu.assertEquals(active_success, true)

    active_success = false
    fpga_signal.active_callback(_, SYSTEM_ID, 'FPGA')
    lu.assertEquals(active_success, true)
end

-- 测试获取固件信息
function TestLogicalFwSignal:test_get_fpga_type()
    local file_path = "/dev/shm/upgrade/Firmware1"
    local ok = pcall(function()
        fpga_signal.get_fpga_type(self, file_path)
    end)
    lu.assertEquals(ok, false)
end

-- 测试fpga flash升级finish流程
function TestLogicalFwSignal:test_upgrade_component_fpga()
    local fpga_signal = {
        fpga_upgrade_type = 'SFC',
        fw_list = {
            {
                system_id = 1,
                csr = {
                    Name = 'FPGA'
                }
            }
        },
        upg_cfg_list = {
            {
                name = "Firmware1",
                uid = 111,
                check_fw_uid_exist = function(fw)
                    return 0
                end
            }
        }
    }
    local file_path = "1"
    local ok = fpga_process:upgrade_component_fpga(fpga_signal, file_path)
    lu.assertEquals(ok, 0)
end

-- 测试fpga flash升级finish flash fail流程
function TestLogicalFwSignal:test_upgrade_component_fpga_flash_err()
    local file_path = "2"
    local fpga_signal = {
        fpga_upgrade_type = 'SFC',
        fw_list = {
            {
                system_id = 1,
                csr = {
                    Name = 'FPGA'
                }
            }
        },
        upg_cfg_list = {
            {
                name = "Firmware1",
                uid = 111,
                check_fw_uid_exist = function(fw)
                    return 0
                end
            }
        }
    }
    local ok = fpga_process:upgrade_component_fpga(fpga_signal, file_path)
    lu.assertEquals(ok, -1)
end

-- 测试fpga flash升级finish jtag fail流程
function TestLogicalFwSignal:test_upgrade_component_fpga_jtag_fail()
    local fpga_signal = {
        fpga_upgrade_type = 'JTAG',
        db = 0,
        fw_list = {
            {
                system_id = 1,
                csr = {
                    Name = 'FPGA'
                }
            }
        },
        upg_cfg_list = {
            {
                name = "Firmware1",
                uid = 111,
                check_fw_uid_exist = function(fw)
                    return 0
                end
            }
        }
    }
    local file_path = "2"
    local ok = fpga_process:upgrade_component_fpga(fpga_signal, file_path)
    lu.assertEquals(ok, -1)
end

-- 测试fpga flash升级finish jtag fail流程
function TestLogicalFwSignal:test_upgrade_component_fpga_jtag()
    local file_path = "1"
    local fpga_signal = {
        fpga_upgrade_type = 'JTAG',
        db = 1,
        fw_list = {
            {
                system_id = 1,
                csr = {
                    Name = 'FPGA'
                }
            }
        },
        upg_cfg_list = {
            {
                name = "Firmware1",
                uid = 111,
                check_fw_uid_exist = function(fw)
                    return 0
                end
            }
        }
    }
    local ok = fpga_process:upgrade_component_fpga(fpga_signal, file_path)
    lu.assertEquals(ok, 0)
end